using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using TesteIATcc.Comuns;
using TesteIATcc;

namespace TesteIATcc.Entidades
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Inimigo : Microsoft.Xna.Framework.GameComponent
    {
        #region atributos
        private Sprite spriteInimigo;
        private Sprite tiroInimigo;
        private Rectangle visaoInimigo;
        private Rectangle visaDesvioInimigo;
        private bool vivo = true;
        private Jogador jogador;

        //parametros do tiro
        private int direcaoTiroY;
        private int direcaoTiroX;

        //parametros do desvio
        private bool desviando = false;
        private int desvioInimigo;
        private int acumuladorDesvio;
        public bool desvioPorPassagem = false;
        #endregion

        #region getters e setters

        public Sprite TiroInimigo
        {
            get { return tiroInimigo; }
            set { tiroInimigo = value; }
        }

        public bool Vivo
        {
            get { return vivo; }
            set { vivo = value; }
        }

        public Sprite SpriteInimigo
        {
            get { return spriteInimigo; }
            set { spriteInimigo = value; }
        }
        #endregion

        public Inimigo(TesteIA game, string qualSpriteInimigo)
            : base(game)
        {
            this.spriteInimigo = new Sprite(game, qualSpriteInimigo, new Vector2(64f, 64f), 0);
            base.Game.Components.Add(this.spriteInimigo);

            this.tiroInimigo = new Sprite(game, "sprites\\tiroinimigo", new Vector2(8f, 8f), 0);

            this.tiroInimigo.Visible = false;
            base.Game.Components.Add(this.tiroInimigo);

            this.visaoInimigo = new Rectangle(0, 0, 128, 128);
            this.visaDesvioInimigo = new Rectangle(0, 0, 96, 96);
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            this.jogador = (Jogador)base.Game.Services.GetService(typeof(Jogador));
            this.reposicionaVisaoDesvioInimigo();
            this.reposicionaVisaoInimigo();
            this.reposicionaTiroNave();
            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            //atualiza o inimigo
            //enquanto o inimigo esta vivo, processa atualizacoes
            //move o sprite
            this.spriteInimigo.PosicaoSprite =
                new Point(this.spriteInimigo.PosicaoSprite.X - 3, this.spriteInimigo.PosicaoSprite.Y);

            this.reposicionaVisaoDesvioInimigo();
            this.reposicionaVisaoInimigo();
            this.reposicionaTiroNave();

            if (this.spriteInimigo.Visible)
            {
                //checa visao pra atirar
                if (this.checaVisaoJogador(this.visaoInimigo))
                {
                    if (!this.tiroInimigo.Visible)
                    {
                        this.atirar(this.jogador.SpriteJogador.PosicaoSprite);
                    }
                }

                //checa visao para desviar
                if (this.checaVisaoJogador(this.visaDesvioInimigo))
                {
                    if (!this.desvioPorPassagem)
                    {
                        if (!this.desviando)
                        {
                            this.RetornaPosicaoYAleatoria();
                            this.desviando = true;
                        }
                        else
                        {
                            this.desvioEixoY();
                        }
                    }
                }
            }
            else
            {
                this.morrer();
            }

            //atualiza o tiro do inimigo
            //verifica se o tiro do inimigo saiu da tela, para pode reposiciona-lo
            if ((this.tiroInimigo.PosicaoSprite.X > base.Game.GraphicsDevice.Viewport.Width) ||
                (this.tiroInimigo.PosicaoSprite.X < 0) ||
                (this.tiroInimigo.PosicaoSprite.Y > base.Game.GraphicsDevice.Viewport.Height) ||
                (this.tiroInimigo.PosicaoSprite.Y < 0))
            {
                this.tiroInimigo.Visible = false;
            }

            //atualiza a trajetoria do tiro
            if (this.tiroInimigo.Visible)
            {
                //7 = velocidade do tiro
                this.tiroInimigo.PosicaoSprite =
                    new Point(this.tiroInimigo.PosicaoSprite.X + (6 * this.direcaoTiroX),
                         this.tiroInimigo.PosicaoSprite.Y + (6 * this.direcaoTiroY));
            }
            else
            {
                this.reposicionaTiroNave();
            }

            base.Update(gameTime);
        }

        private bool checaVisaoJogador(Rectangle retVisao)
        {
            if (retVisao.Intersects(
                new Rectangle(this.jogador.SpriteJogador.PosicaoSprite.X,
                    this.jogador.SpriteJogador.PosicaoSprite.Y,
                    (int)this.jogador.SpriteJogador.TamanhoSprite.X,
                    (int)this.jogador.SpriteJogador.TamanhoSprite.Y)))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private void atirar(Point direcaoTiro)
        {
            //verifica se o tiro tem que sair pra esquerda ou pra direita do inimigo, dependendo de onde esta o jogador
            if (direcaoTiro.X > this.spriteInimigo.PosicaoSprite.X)
            {
                this.direcaoTiroX = 1;
            }
            else
            {
                this.direcaoTiroX = -1;
            }

            //passa a posicao Y do inimigo, para onde o tiro tem que 
            if (direcaoTiro.Y > this.spriteInimigo.PosicaoSprite.Y)
            {
                this.direcaoTiroY = 1;
            }
            else
            {
                this.direcaoTiroY = -1;
            }

            //this.direcaoTiroY = direcaoTiro.Y;
            this.tiroInimigo.Visible = true;
        }

        private void morrer()
        {
            //definir o sprite de explosao e sumir com o sprite da nave
        }

        private void reposicionaVisaoDesvioInimigo()
        {
            this.visaDesvioInimigo =
                new Rectangle(this.spriteInimigo.PosicaoSprite.X - 32,
                    this.spriteInimigo.PosicaoSprite.Y - 32,
                    this.visaDesvioInimigo.Width,
                    this.visaDesvioInimigo.Height
                    );
        }

        private void reposicionaVisaoInimigo()
        {
            this.visaoInimigo =
               new Rectangle(this.spriteInimigo.PosicaoSprite.X - 64,
                   this.spriteInimigo.PosicaoSprite.Y - 64,
                   this.visaoInimigo.Width,
                   this.visaoInimigo.Height
                   );
        }

        public void reposicionaTiroNave()
        {
            //se o tiro nao estiver visivel na tela, reposiciona ele "embaixo" do inimigo
            if (!this.tiroInimigo.Visible)
            {
                this.tiroInimigo.PosicaoSprite = new Point(this.spriteInimigo.PosicaoSprite.X + (int)this.spriteInimigo.TamanhoSprite.X / 2,
                    this.spriteInimigo.PosicaoSprite.Y + (int)this.spriteInimigo.TamanhoSprite.Y / 2);
            }
        }

        private void desvioEixoY()
        {
            this.spriteInimigo.PosicaoSprite =
                new Point(this.spriteInimigo.PosicaoSprite.X, this.spriteInimigo.PosicaoSprite.Y + (this.desvioInimigo * 3));

            this.acumuladorDesvio += 3;

            if (this.acumuladorDesvio >= this.spriteInimigo.TamanhoSprite.Y)
            {
                this.desviando = false;
                acumuladorDesvio = 0;
                this.desvioPorPassagem = true;
            }
        }

        public void RetornaPosicaoYAleatoria()
        {
            Random r = new Random();
            this.desvioInimigo = r.Next(1, 10); //0 = cima, 1 = baixo

            if (this.desvioInimigo >= 5)
            {
                this.desvioInimigo = 1;
            }
            else
            {
                this.desvioInimigo = -1;
            }
        }
    }
}